package com.faceye.core.service.impl;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.faceye.core.service.StorageService;
import com.faceye.core.service.model.WriteResult;
import com.faceye.core.util.DirectoryUtil;
import com.faceye.core.util.id.IDGenerator;
import com.faceye.core.util.os.OSUtil;
import com.google.common.primitives.Bytes;

@Service
public class StorageServiceImpl implements StorageService {
	private Logger logger = LoggerFactory.getLogger(getClass());

	private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
	//默认上传目录，windows :c:/tmp;mac,linux /tmp
	private static  String DEFAULT_DEFAULT_UPLOAD_DIR=OSUtil.isWindows()?"c:/tmp/":"/tmp";//默认上传目录
	// ID生成器，雪花ID,新文件名使用雪花ID生成
	private IDGenerator idGenerator = new IDGenerator(0, 0);
	// 上传目录,默认存储目录
	@Value("${faceye.upload.dir:/tmp}")
	private String storageDir = "";
	
	@Value("${faceye.img.host:localhost}")
	private String imgHost="";

	/**
	 * Spring MVC 文件上传
	 */
	@Override
	public WriteResult write(MultipartFile file) {
		boolean uploadRes = false;
		WriteResult result = new WriteResult();
		String absolutePath = "";// 上传文件绝对路径
		String relativePath = "";// 上传文件相对路径
		String originalFilename = file.getOriginalFilename();// 原始文件名
		String relativeUploadDir = this.generateRelativeUploadDir();// 上传文件相对目录（相对上传根目录）
		String absoluteUploadDir = this.generateAbsoluteUploadDir(relativeUploadDir);// 上传文件绝对目录
		String generateFilename = this.generateFilename(originalFilename);// 生成的随机文件名
		absolutePath = absoluteUploadDir;
		absolutePath += generateFilename;//上传文件绝对路径
		relativePath = relativeUploadDir;
		relativePath += generateFilename;//上传文件相对路径
		try {
			byte bytes[] = file.getBytes();
			if (bytes != null) {
				uploadRes = this.write(bytes, absolutePath);
			}
		} catch (IOException e) {
			logger.error(">>FaceYe Throws Exception:", e);
		}
		if (uploadRes) {
			result = new WriteResult();
			result.setAbsolutePath(absolutePath);
			result.setRelativePath(relativePath);
			result.setFilename(generateFilename);
			result.setOriginalFilename(originalFilename);
		}
		return result;
	}

	/**
	 * 获取上传目录
	 * @return
	 * @Desc:
	 * @Author:haipenge
	 * @Date:2018年8月8日 上午9:45:03
	 */
	public String getStorageDir(){
		String res="";
		if(StringUtils.isNotEmpty(storageDir)){
			res=storageDir;
		}else{
			res=DEFAULT_DEFAULT_UPLOAD_DIR;
		}
		return res;
	}
	
	/**
	 * 获取图片服务器主机地址
	 * @return
	 * @Desc:
	 * @Author:haipenge
	 * @Date:2018年8月9日 上午11:08:08
	 */
	public String getImgHost(){
		return imgHost;
	}
	
	public String getMimeType(File file) {
		String mimetype = "";
		if (file.exists()) {
			String  suffix=StringUtils.substring(file.getName(), StringUtils.lastIndexOf(file.getName(), ".")+1);
			if (StringUtils.equalsAnyIgnoreCase(suffix, "png")) {
				mimetype = "image/png";
			} else if (StringUtils.equalsAnyIgnoreCase(suffix, "jpg")) {
				mimetype = "image/jpg";
			} else if (StringUtils.equalsAnyIgnoreCase(suffix, "jpeg")) {
				mimetype = "image/jpeg";
			} else if (StringUtils.equalsAnyIgnoreCase(suffix, "gif")) {
				mimetype = "image/gif";
			} else if (StringUtils.equalsAnyIgnoreCase(suffix, "doc")||StringUtils.equalsAnyIgnoreCase(suffix, "docx")) {
				mimetype = "application/x-msword";
				// application/msword
				// application/vnd.ms-word
				mimetype = "application/vnd.ms-word";
			} else if (StringUtils.equalsAnyIgnoreCase(suffix, "xls")||StringUtils.equalsAnyIgnoreCase(suffix, "xlsx")) {
				mimetype = "application/vnd.ms-excel";
			} else if (StringUtils.equalsAnyIgnoreCase(suffix, "pdf")) {
				mimetype = "application/pdf";
			} else {
				javax.activation.MimetypesFileTypeMap mtMap = new javax.activation.MimetypesFileTypeMap();
				mimetype = mtMap.getContentType(file);
			}
		}
		return mimetype;
	}
	/**
	 * 生成文件名
	 * 
	 * @param originalFilename
	 * @return
	 * @Desc:
	 * @Author:haipenge
	 * @Date:2018年8月5日 下午4:18:37
	 */
	private String generateFilename(String originalFilename) {
		String res = "";
		String suffix = "";
		if (StringUtils.isNotEmpty(originalFilename)) {
			if (StringUtils.contains(originalFilename, ".")) {
				suffix = StringUtils.substring(originalFilename, StringUtils.lastIndexOf(originalFilename, "."));
				logger.debug(">>FaceYe --> file suffix is:" + suffix);
			}
			res = "" + idGenerator.nextId() + suffix;
		} else {
			logger.error(">>FaceYe original filename is null.");
		}
		return res;
	}

	/**
	 * 生成上传目录(相对路径，相对于上传目录）：year/month/day/hour/min/second/
	 * 
	 * @return
	 * @Desc:
	 * @Author:haipenge
	 * @Date:2018年8月5日 下午4:34:59
	 */
	private String generateRelativeUploadDir() {
		return DirectoryUtil.date2Dirs(new Date());
	}

	/**
	 * 取得上传绝结路径
	 * 
	 * @param relativeUploadDir
	 * @return
	 * @Desc:
	 * @Author:haipenge
	 * @Date:2018年8月5日 下午4:59:33
	 */
	private String generateAbsoluteUploadDir(String relativeUploadDir) {
		String dir = "";
		StringBuilder sb = new StringBuilder();
		sb.append(this.getStorageDir());
		if (!StringUtils.endsWith(this.getStorageDir(), File.separator)) {
			sb.append(File.separator);
		}
		sb.append(this.generateRelativeUploadDir());
		dir = sb.toString();
		return dir;
	}


	private boolean write(byte bytes[], String absolutePath) {
		boolean res = false;
		String path = "";
		String filename = "";
		if (bytes == null) {
			logger.error(">>FaceYe --write bytes[] is null.");
			return res;
		}
		// 分离文件名与目录
		if (StringUtils.isNotEmpty(absolutePath)) {
			path = StringUtils.substring(absolutePath, 0, StringUtils.lastIndexOf(absolutePath, File.separator));
			filename = StringUtils.substring(absolutePath, StringUtils.lastIndexOf(absolutePath, File.separator) + 1);
		} else {
			logger.error(">>FaceYe write absolutePaht is null.");
			return res;
		}
		// 创建目录
		if (StringUtils.isNotEmpty(path)) {
			File file = new File(path);
			if (!file.exists()) {
				file.mkdirs();
			}
		}
		OutputStream os = null;
		try {
			// 如果文件不存在，创建文件
			File writeFile = new File(absolutePath);
			if (!writeFile.exists()) {
				writeFile.createNewFile();
			}
			os = new BufferedOutputStream(new FileOutputStream(writeFile));
			IOUtils.write(bytes, os);
			os.flush();
			res=true;
		} catch (IOException e1) {
			logger.error(">>FaceYe Throws Exception:", e1);
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					logger.error(">>FaceYe Throws Exception:", e);
				}
			}
		}
		// BufferedOutputStream bos = null;
		// try {
		// //如果文件不存在，创建文件
		// File writeFile = new File(absolutePath);
		// if(!writeFile.exists()){
		// writeFile.createNewFile();
		// }
		// bos = new BufferedOutputStream(new FileOutputStream(writeFile));
		// bos.write(bytes);
		// bos.flush();
		// res =true;
		// } catch (FileNotFoundException e) {
		// logger.error(">>FaceYe Throws Exception:",e);
		// } catch (IOException e) {
		// logger.error(">>FaceYe Throws Exception:",e);
		// }finally{
		// if(bos!=null){
		// try {
		// bos.close();
		// } catch (IOException e) {
		// logger.error(">>FaceYe Throws Exception:",e);
		// }
		// }
		// }
		return res;
	}

}
